package controller.datasource;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Locale;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import dbsync4j.core.behavior.DBSyncManager;
import dbsync4j.core.behavior.Schema;
import dbsync4j.core.behavior.Server;
import dbsync4j.core.concrete.ConcreteDBSyncManager;
import dbsync4j.core.concrete.ConcreteServer;
import dbsync4j.core.exception.DataSourceException;
import dbsync4j.core.exception.DataSourceMissingParameters;
import dbsync4j.core.types.DatabaseType;

public class DataSourceConfigure extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)	throws ServletException, IOException {

		String  dispatcher = "/jsp/configureservers.jsp";
		Server servidorOrigem = (Server) req.getSession(false).getAttribute("sOrigem");
		Server servidorDestino = (Server) req.getSession(false).getAttribute("sDestino");

		String dadosOrigem = req.getParameter("statusOrigem");
		String dadosDestino = req.getParameter("statusDestino");
		String mensagem = "";


		/* verifica se foi o formul�rio de origem quem fez a requisisi��o */
		if(dadosOrigem != null) {
			/* Recupera o status, conectado ou desconectado. Este valor provem de um campo escondido no formul�rio de origem */
			String status = req.getParameter("statusOrigem");

			/* se estiver desconectado */
			if(status.equals("disconnected")) {

				try {

					/* conecta nos servidor */
					servidorOrigem = getServer(req);

					/* seta o servidor de origem*/
					req.setAttribute("serverOrigem", servidorOrigem);

					req.setAttribute("sDatabaseType", req.getParameter("banco"));

					/* coloca o objeto na sess�o */
					req.getSession(false).setAttribute("sOrigem", servidorOrigem);

					DBSyncManager manager = new ConcreteDBSyncManager();
					manager.setLocale(new Locale("en","US"));
					manager.connectServer(servidorOrigem);
					Schema schemaOrigem = manager.loadSchema(servidorOrigem);
					req.getSession(false).setAttribute("schemaOrigem", schemaOrigem);

					/* trata os erros e limpa as variaveis */
				} catch (DataSourceMissingParameters e) {

					servidorOrigem = null;
					mensagem = "Preencha todos os campos!";
				} catch (DataSourceException e) {

					servidorOrigem = null;
					mensagem = "N�o foi poss�vel conectar ao Servidor de Origem";
				}

			} else if(status.equals("connected")) {

				try {

					Server sOrigem = (Server) req.getSession(false).getAttribute("sOrigem");
					Schema schemaOrigem = (Schema) req.getSession(false).getAttribute("schemaOrigem");
					sOrigem.disconnect();

					sOrigem = null;
					schemaOrigem = null;					

					req.getSession(false).setAttribute("sOrigem", sOrigem);	
					req.getSession(false).setAttribute("schemaOrigem", schemaOrigem);	

					req.setAttribute("serverOrigem", sOrigem);

				} catch (SQLException e) {
					mensagem = "Falha ao Desconectar! Contate o administrador do sistema.";
					e.printStackTrace();
				}
			}

			/* seta a mensagem de erro */
			req.setAttribute("mensagemErroOrigem", mensagem);
			/* seta o servidor de destino caso o mesmo j� tenha sido conectado */
			req.setAttribute("serverDestino", servidorDestino);

			/* se n�o ...
			 * verifica se foi o formul�rio de destino quem fez a requisi��o 
			 */
		} else if(dadosDestino != null) {

			/* Recupera o status, conectado ou desconectado. Este valor provem de um campo escondido no formul�rio de destino */
			String status = req.getParameter("statusDestino");

			/* se estiver desconectado */
			if(status.equals("disconnected" )){

				try {

					/* conecta nos servidor */
					servidorDestino = getServer(req);

					/* seta o servidor de destino*/
					req.setAttribute("serverDestino", servidorDestino);

					req.setAttribute("dDatabaseType", req.getParameter("banco"));

					DBSyncManager manager = new ConcreteDBSyncManager();
					manager.connectServer(servidorDestino);
					Schema schemaDestino = manager.loadSchema(servidorDestino);
					req.getSession(false).setAttribute("schemaDestino", schemaDestino);

					/* coloca o objeto na sess�o */
					req.getSession(false).setAttribute("sDestino", servidorDestino);

					/* trata os erros e limpa as variaveis */
				} catch (DataSourceMissingParameters e) {

					servidorDestino = null;
					mensagem = "Preencha todos os campos!";
				} catch (DataSourceException e) {

					servidorDestino = null;
					mensagem = "N�o foi poss�vel conectar ao Servidor de Destino";
				}		

			} else if(status.equals("connected")) {
				try {

					Server sDestino = (Server) req.getSession(false).getAttribute("sDestino");
					Schema schemaDestino = (Schema) req.getSession(false).getAttribute("schemaDestino");
					sDestino.disconnect();

					sDestino = null;
					schemaDestino = null;

					req.getSession(false).setAttribute("sDestino", sDestino);		
					req.getSession(false).setAttribute("schemaDestino", schemaDestino);	

					req.setAttribute("serverDestino", sDestino);

				} catch (SQLException e) {
					mensagem = "Falha ao Desconectar! Contate o administrador do sistema.";
					e.printStackTrace();
				}
			}

			/* seta a mensagem de erro */
			req.setAttribute("mensagemErroDestino", mensagem);
			/* seta o servidor de origem caso o mesmo j� tenha sido conectado */
			req.setAttribute("serverOrigem", servidorOrigem);

		} else if(servidorDestino == null && servidorOrigem == null) {
			dispatcher = "/jsp/configureservers.jsp";
			req.setAttribute("serverOrigem", servidorOrigem);
			req.setAttribute("serverDestino", servidorDestino);
		}

		RequestDispatcher requestDispatcher = req.getRequestDispatcher(dispatcher);
		requestDispatcher.forward(req, resp);
	}

	private Server getServer(HttpServletRequest req) throws DataSourceException, DataSourceMissingParameters {

		String serverName = req.getParameter("servidor");
		String userName = req.getParameter("usuario");
		String pass = req.getParameter("senha");
		String url = req.getParameter("url");
		String database = req.getParameter("banco");

		if(serverName == null || userName == null || pass == null || url == null || database == null) {
			throw new DataSourceMissingParameters("Preencha todos os campos");
		}

		DatabaseType databaseType = null;

		switch (Integer.valueOf(database)) {
			case 0: databaseType = DatabaseType.POSTGRESQL; break;
			case 1: databaseType = DatabaseType.MYSQL; break;
			case 2: databaseType = DatabaseType.SQLSERVER_JTDS; break;
		}

		Server server = new ConcreteServer();
		server.setName(serverName);
		server.setUsername(userName);
		server.setPassword(pass);
		server.setDatabaseType(databaseType);
		server.setServerUrl(url);

		server.connect();

		return server;
	}

}
